package org.obs.controller;

import java.util.Enumeration;
import java.util.Properties;

import javax.servlet.Servlet;
import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.directwebremoting.annotations.RemoteProxy;
import org.springframework.context.ApplicationContext;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.ServletWrappingController;

public class DwrControllerWrapper extends ServletWrappingController {

    private Properties properties = new Properties();

    private Servlet servletInstance;

    private Class servletClass;

    @Override
    public void afterPropertiesSet() throws Exception {
        ApplicationContext context = getApplicationContext();
        String classes = "";
        while (context != null) {
            String[] beans = context.getBeanDefinitionNames();
            Class clazz = null;
            for (String beanName : beans) {
                try {
                    clazz = context.getType(beanName);
                } catch (RuntimeException e) {
                    continue;
                }
                if (clazz == null) {
                    continue;
                }
                if (clazz.isAnnotationPresent(RemoteProxy.class)) {
                    classes += clazz.getCanonicalName()
                                + "\n";
                }
            }
            context = context.getParent();
        }
        properties.setProperty("classes", classes);
        properties.setProperty("debug", "true");
        this.servletInstance = (Servlet) servletClass.newInstance();
        this.servletInstance.init(new DelegatingServletConfig());
    }

    @Override
    protected ModelAndView handleRequestInternal(HttpServletRequest request,
            HttpServletResponse response) throws Exception {

        servletInstance.service(request, response);
        return null;
    }

    protected class DelegatingServletConfig implements ServletConfig {

        public String getServletName() {
            return getServletName();
        }

        public ServletContext getServletContext() {
            return DwrControllerWrapper.this.getServletContext();
        }

        public String getInitParameter(String paramName) {
            return properties.getProperty(paramName);
        }

        public Enumeration getInitParameterNames() {
            return properties.keys();
        }
    }

    public Class<?> getServletClass() {
        return servletClass;
    }

    @Override
    public void setServletClass(Class servletClass) {
        this.servletClass = servletClass;
    }
}
